package cn.com.blueInfo.bpm.template.repository.impl;

import cn.com.blueInfo.bpm.common.entity.BaseEntity;
import cn.com.blueInfo.bpm.common.enums.BaseDeleted;
import cn.com.blueInfo.bpm.common.repository.BaseRepository;
import cn.com.blueInfo.bpm.template.entity.File;
import cn.com.blueInfo.bpm.template.mapper.FileMapper;
import cn.com.blueInfo.bpm.template.repository.FileRepository;
import cn.com.blueInfo.bpm.template.request.FileDTO;
import cn.com.blueInfo.core.entity.CurrentLoginUserInfo;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.support.SFunction;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.log4j.Log4j2;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * 流程附件管理表 数据服务实现类
 * @author suxch
 * @since 2025-09-01 19:30:44
 */
@Log4j2
@Service
public class FileRepositoryImpl
        extends ServiceImpl<FileMapper, File>
        implements FileRepository, BaseRepository<File, FileDTO.QueryDTO> {

    @Autowired
    private CurrentLoginUserInfo currentLoginUserInfo;

    /**
     * 提供获取 CurrentLoginUserInfo 的方法（由实现类提供，避免接口中注入）
     * @return CurrentLoginUserInfo
     */
    @Override
    public CurrentLoginUserInfo getCurrentLoginUserInfo() {
        return currentLoginUserInfo;
    }

    /**
     * 新增流程附件管理
     * @param file 流程附件管理参数
     */
    @Override
    public Integer createFile(File file) {
        return sqlExecuteResult(save(file));
    }

    /**
     * 批量新增流程附件管理
     * @param fileList 流程附件管理参数列表
     */
    @Override
    public Integer batchCreateFile(List<File> fileList) {
        return sqlExecuteResult(saveBatch(fileList), fileList.size());
    }

    /**
     * 删除流程附件管理
     * @param fileId 流程附件管理ID
     */
    @Override
    public Integer deleteFile(Long fileId) {
        File file = new File();
        file.setId(fileId);
        file.setDeleted(BaseDeleted.DELETED);
        return sqlExecuteResult(removeById(file));
    }

    /**
     * 批量删除流程附件管理
     * @param fileIdList 流程附件管理ID列表
     */
    @Override
    public Integer batchDeleteFile(List<Long> fileIdList) {
        List<File> fileList = new ArrayList<>();
        for (Long fileId : fileIdList) {
            File file = new File();
            file.setId(fileId);
            file.setDeleted(BaseDeleted.DELETED);
            fileList.add(file);
        }
        return sqlExecuteResult(removeBatchByIds(fileList), fileList.size());
    }

    /**
     * 更新部分流程附件管理
     * @param file 流程附件管理参数
     */
    @Override
    public Integer updateFilePartial(File file) {
        validateUpdateId(file.getId());
        LambdaUpdateWrapper<File> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.eq(File::getId, file.getId());
        return sqlExecuteResult(update(updateWrapper));
    }

    /**
     * 更新全部流程附件管理
     * @param file 流程附件管理参数
     */
    @Override
    public Integer updateFile(File file) {
        validateUpdateId(file.getId());
        return sqlExecuteResult(updateById(file));
    }

    /**
     * 查询一条流程附件管理
     * @param fileId 流程附件管理ID
     */
    @Override
    public File getFileById(Long fileId) {
        LambdaQueryWrapper<File> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(File::getId, fileId);
        return getOne(queryWrapper);
    }

    /**
     * 分页查询流程附件管理
     * @param fileQueryDTO 流程附件管理参数
     */
    @Override
    public Page<File> getFilePage(FileDTO.QueryDTO fileQueryDTO) {
        Page<File> filePage = new Page<>(
                fileQueryDTO.getPage(), fileQueryDTO.getSize());
        LambdaQueryWrapper<File> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper(queryWrapper, fileQueryDTO);

        BaseDeleted deleted = fileQueryDTO.getDeleted();
        if (ObjectUtils.isNotEmpty(deleted) && deleted.equals(BaseDeleted.DELETED)) {
            return baseMapper.selectDeletePage(filePage, queryWrapper);
        } else {
            return page(filePage, queryWrapper);
        }
    }

    /**
     * 根据条件查询 流程附件管理 数量
     * @param fileQueryDTO 流程附件管理参数
     */
    @Override
    public Long getFileCount(FileDTO.QueryDTO fileQueryDTO) {
        LambdaQueryWrapper<File> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper(queryWrapper, fileQueryDTO);

        BaseDeleted deleted = fileQueryDTO.getDeleted();
        if (ObjectUtils.isNotEmpty(deleted) && deleted.equals(BaseDeleted.DELETED)) {
            return baseMapper.selectDeleteCount(queryWrapper);
        } else {
            return count(queryWrapper);
        }
    }

    /**
     * 根据条件查询 流程附件管理
     * @param fileQueryDTO 流程附件管理参数
     */
    @Override
    public List<File> getFileList(FileDTO.QueryDTO fileQueryDTO) {
        LambdaQueryWrapper<File> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper(queryWrapper, fileQueryDTO);

        BaseDeleted deleted = fileQueryDTO.getDeleted();
        if (ObjectUtils.isNotEmpty(deleted) && deleted.equals(BaseDeleted.DELETED)) {
            return baseMapper.selectDeleteList(queryWrapper);
        } else {
            return list(queryWrapper);
        }
    }

    private void queryWrapper(LambdaQueryWrapper<File> queryWrapper, FileDTO.QueryDTO fileQueryDTO) {

        Long instanceId = fileQueryDTO.getInstanceId();
        queryWrapper.eq(ObjectUtils.isNotEmpty(instanceId), File::getInstanceId, instanceId);

        Long workItemId = fileQueryDTO.getWorkItemId();
        queryWrapper.eq(ObjectUtils.isNotEmpty(workItemId), File::getWorkItemId, workItemId);

        String fileName = fileQueryDTO.getFileName();
        queryWrapper.eq(StringUtils.isNotBlank(fileName), File::getFileName, fileName);

        String filePath = fileQueryDTO.getFilePath();
        queryWrapper.eq(StringUtils.isNotBlank(filePath), File::getFilePath, filePath);

        Long fileSize = fileQueryDTO.getFileSize();
        queryWrapper.eq(ObjectUtils.isNotEmpty(fileSize), File::getFileSize, fileSize);

        String fileType = fileQueryDTO.getFileType();
        queryWrapper.eq(StringUtils.isNotBlank(fileType), File::getFileType, fileType);

        Long uploadUserId = fileQueryDTO.getUploadUserId();
        queryWrapper.eq(ObjectUtils.isNotEmpty(uploadUserId), File::getUploadUserId, fileType);

        LocalDateTime uploadTime = fileQueryDTO.getUploadTime();
        queryWrapper.eq(ObjectUtils.isNotEmpty(uploadTime), File::getUploadTime, uploadTime);

        addQueryWrapper(queryWrapper, fileQueryDTO, getCommonColumn());

    }

    private Map<String, SFunction<File, ?>> getCommonColumn() {
        return BaseEntity.getCommonColumn(
                File::getOrderNumber,
                File::getTenantId,
                File::getApplicationId,
                File::getStatus,
                File::getDeleted,
                File::getDeleteUserId,
                File::getDeleteTime,
                File::getRemark,
                File::getCreateUserId,
                File::getCreateTime,
                File::getUpdateUserId,
                File::getUpdateTime,
                File::getExtend1,
                File::getExtend2,
                File::getExtend3);
    }

}
